home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UScroller.cp < prev    next >
Text File  |  1991-05-01  |  21KB  |  780 lines

  1. // UScroller.cp 
  2. // Copyright © 1987-1991 by Apple Computer Inc.    All rights reserved.
  3.  
  4. #ifndef __UGEOMETRY__
  5. #include <UGeometry.h>
  6. #endif
  7.  
  8. #ifndef __ULIST__
  9. #include <UList.h>
  10. #endif
  11.  
  12. #ifndef __UEVENT__
  13. #include <UEvent.h>
  14. #endif
  15.  
  16. #ifndef __UCOMMAND__
  17. #include <UCommand.h>
  18. #endif
  19.  
  20. #ifndef __UDOCUMENT__
  21. #include <UDocument.h>
  22. #endif
  23.  
  24. #ifndef __CONTROLS__
  25. #include <Controls.h>
  26. #endif
  27.  
  28. #ifndef __UCONTROL__
  29. #include <UControl.h>
  30. #endif
  31.  
  32. #ifndef __UFAILURE__
  33. #include <UFailure.h>
  34. #endif
  35.  
  36. #ifndef __UMACAPPUTILITIES__
  37. #include <UMacAppUtilities.h>
  38. #endif
  39.  
  40. #ifndef __DIALOGS__
  41. #include <Dialogs.h>
  42. #endif
  43.  
  44. #ifndef __UPATCH__
  45. #include <UPatch.h>
  46. #endif
  47.  
  48. #ifndef __UMACAPPGLOBALS__
  49. #include <UMacAppGlobals.h>
  50. #endif
  51.  
  52. #ifndef __STDLIB__
  53. #include "StdLib.h"
  54. #endif
  55.  
  56. #ifndef __UVIEWSERVER__
  57. #include <UViewServer.h>
  58. #endif
  59.  
  60. #ifndef __USCROLLER__
  61. #include "UScroller.h"
  62. #endif
  63.  
  64. //--------------------------------------------------------------------------------------------------
  65. #pragma segment MAOpen
  66.  
  67. pascal void TScroller::Initialize(void)            // override 
  68. {
  69.     inherited::Initialize();
  70.     
  71.     fConstrain[hSel] = FALSE;
  72.     fConstrain[vSel] = FALSE;
  73.     fMaxTranslation = gZeroVPt;
  74.     fRespondsToFunctionKeys = TRUE;
  75.     fSBarOffsets = gZeroVRect;
  76.     fScrollBars[hSel] = NULL;
  77.     fScrollBars[vSel] = NULL;
  78.     fScrollLimit = gZeroVPt;
  79.     fScrollUnit = VPoint(kStdScrollUnit, kStdScrollUnit);
  80. }
  81.  
  82. //--------------------------------------------------------------------------------------------------
  83. #pragma segment MAOpen
  84.  
  85. pascal void TScroller::IScroller(TView* itsSuperView,
  86.                                  const VPoint& itsLocation,
  87.                                  const VPoint& itsSize,
  88.                                  SizeDeterminer itsHSizeDet,
  89.                                  SizeDeterminer itsVSizeDet,
  90.                                  const VPoint& itsMax,
  91.                                  Boolean wantHorzSBar,
  92.                                  Boolean wantVertSBar)
  93.  
  94. {
  95.     TDocument * itsSuperViewsDocument = NULL;
  96.  
  97.     if (itsSuperView)
  98.         itsSuperViewsDocument = itsSuperView->fDocument;
  99.  
  100.     this->IView(itsSuperViewsDocument, itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet);
  101.  
  102.     this->SetScrollParameters(VPoint(kStdScrollUnit, kStdScrollUnit), FALSE, FALSE);
  103.  
  104.     this->SetScrollLimits(itsMax, kDontRedraw);
  105.  
  106.     if (wantHorzSBar)
  107.         this->CreateScrollBar(hSel);
  108.     if (wantVertSBar)
  109.         this->CreateScrollBar(vSel);
  110.     if (wantHorzSBar || wantVertSBar)
  111.         this->AdjustScrollBars(kDontInvalidate);
  112. }
  113.  
  114. //--------------------------------------------------------------------------------------------------
  115. #pragma segment MAOpen
  116.  
  117. pascal void TScroller::IRes(TDocument* itsDocument,
  118.                             TView* itsSuperView,
  119.                             Ptr& itsParams)
  120. {
  121.     VPoint scrollLimit;
  122.     VCoordinate horzUnits;
  123.     VCoordinate vertUnits;
  124.     Boolean horzConstraint;
  125.     Boolean vertConstraint;
  126.     Rect sBarOffsets;
  127.     Boolean wantHSBar;
  128.     Boolean wantVSBar;
  129.  
  130.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  131.  
  132.     {    // Remember: itsParams could be a pointer into a relocatable block!
  133.         // So, retrieve the values from the template into locals
  134.         // so that we can pass the values into methods that may move memory.
  135.     
  136.         ScrollerTemplate& templateData = *((ScrollerTemplate *) itsParams);
  137.     
  138.         scrollLimit.h = templateData.horzMax;
  139.         scrollLimit.v = templateData.vertMax;
  140.         horzUnits = templateData.hScrollUnits;
  141.         vertUnits = templateData.vScrollUnits;
  142.         horzConstraint = templateData.hConstrain;
  143.         vertConstraint = templateData.vConstrain;
  144.         sBarOffsets = templateData.sBarOffsets;
  145.         wantHSBar = templateData.wantHSBar;
  146.         wantVSBar = templateData.wantVSBar;
  147.     }
  148.  
  149.     this->SetScrollLimits(scrollLimit, kDontRedraw);
  150.  
  151.     this->SetScrollParameters(VPoint(vertUnits, horzUnits), horzConstraint, vertConstraint);
  152.     fSBarOffsets = sBarOffsets;
  153.  
  154.     if (wantHSBar)
  155.         this->CreateTemplateScrollBar(hSel);
  156.     if (wantVSBar)
  157.         this->CreateTemplateScrollBar(vSel);
  158.     if (wantHSBar || wantVSBar)
  159.         this->AdjustScrollBars(kDontInvalidate);
  160.  
  161.     OffsetPtr(itsParams, sizeof(ScrollerTemplate));
  162. }
  163.  
  164. //--------------------------------------------------------------------------------------------------
  165. #pragma segment MAScrollerRes
  166.  
  167. pascal TObject* TScroller::Clone(void)            // override 
  168. {
  169.     TScroller * aClonedScroller;
  170.  
  171.     aClonedScroller = (TScroller *)(inherited::Clone());
  172.  
  173.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  174.     {
  175.         if (aClonedScroller->fScrollBars[vhs])
  176.         {
  177.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  178.             TScrollerScrollBar *temp = (TScrollerScrollBar *)(aClonedScroller->fScrollBars[vhs]->Clone());
  179.             aClonedScroller->fScrollBars[vhs] = temp;
  180.             aClonedScroller->fScrollBars[vhs]->AttachScroller(this);
  181.         }
  182.     }
  183.     return aClonedScroller;
  184. }
  185.  
  186. //--------------------------------------------------------------------------------------------------
  187. #pragma segment MAWriteRes
  188.  
  189. pascal void TScroller::WRes(ViewRsrcHandle theResource,
  190.                             Ptr& itsParams)        // override 
  191. {
  192.     ScrollerTemplatePtr scPtr;
  193.     VRect aVRect;
  194.  
  195.     inherited::WRes(theResource, itsParams);
  196.  
  197.     scPtr = (ScrollerTemplatePtr)(ExpandPtr((Handle)theResource, itsParams, sizeof(ScrollerTemplate)));
  198.  
  199.     scPtr->wantHSBar = (fScrollBars[hSel] != NULL);
  200.     scPtr->wantVSBar = (fScrollBars[vSel] != NULL);
  201.     scPtr->vertMax = fScrollLimit.v;
  202.     scPtr->horzMax = fScrollLimit.h;
  203.     scPtr->vScrollUnits = (short)fScrollUnit.v;
  204.     scPtr->hScrollUnits = (short)fScrollUnit.h;
  205.     scPtr->vConstrain = fConstrain[vSel];
  206.     scPtr->hConstrain = fConstrain[hSel];
  207.     aVRect = fSBarOffsets;
  208.     scPtr->sBarOffsets = aVRect;
  209. }
  210.  
  211. //--------------------------------------------------------------------------------------------------
  212. #pragma segment MAWriteRes
  213.  
  214. pascal void TScroller::WriteRes(ViewRsrcHandle theResource,
  215.                                 Ptr& itsParams)    // override 
  216. {
  217.     gWResSignature = 'scrl';
  218.     gWResType = "TScroller";
  219.     this->WRes(theResource, itsParams);
  220. }
  221.  
  222. //--------------------------------------------------------------------------------------------------
  223. #pragma segment MAClose
  224.  
  225. pascal void TScroller::Free(void)                // override 
  226. {
  227.     // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  228.     TScrollerScrollBar *temp = (TScrollerScrollBar *)(FreeIfObject(fScrollBars[hSel]));
  229.     fScrollBars[hSel] = temp;
  230.     // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  231.     temp = (TScrollerScrollBar *)(FreeIfObject(fScrollBars[vSel]));
  232.     fScrollBars[vSel] = temp;
  233.  
  234.     inherited::Free();
  235. }
  236.  
  237. //--------------------------------------------------------------------------------------------------
  238. #pragma segment MAOpen
  239.  
  240. pascal void TScroller::AddSubView(TView* theSubView)// override 
  241. {
  242.     inherited::AddSubView(theSubView);
  243.     theSubView->BeInScroller(this);
  244. }
  245.  
  246. //--------------------------------------------------------------------------------------------------
  247. #pragma segment MANonRes
  248.  
  249. pascal void TScroller::AdjustScrollBars(Boolean invalidate)
  250. {
  251.     TScrollBar * aScrollBar;
  252.     VHSelect ortho;
  253.     VPoint loc;
  254.     VPoint size;
  255.  
  256.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  257.     {
  258.         aScrollBar = fScrollBars[vhs];
  259.         if (aScrollBar)
  260.         {
  261.             ortho = gOrthogonal[vhs];
  262.             loc = fLocation;
  263.             size = fSize;
  264.  
  265.             loc[vhs] += fSBarOffsets[topLeft][vhs] - 1;
  266.             loc[ortho] += size[ortho];
  267.  
  268.             size[vhs] = size[vhs] - fSBarOffsets[topLeft][vhs] + fSBarOffsets[botRight][vhs] + 2;
  269.             size[ortho] = kSBarSize;
  270.  
  271.             aScrollBar->Resize(size, invalidate);
  272.             aScrollBar->Locate(loc, invalidate);
  273.         }
  274.     }
  275. }
  276.  
  277. //--------------------------------------------------------------------------------------------------
  278. #pragma segment MADoCommand
  279.  
  280. pascal VCoordinate ProportionalScroll(VCoordinate diff,
  281.                                       VPoint scrollUnit,
  282.                                       VCoordinate maxTranslationchange,
  283.                                       VHSelect vhs)
  284. {
  285.     if (scrollUnit[vhs] != 0)
  286.         return MinMax(scrollUnit[vhs], IntMultiply((short)(((short)diff + ((short)scrollUnit[vhs] / 2)) / scrollUnit[vhs]), (short)scrollUnit[vhs]), maxTranslationchange);
  287.     else
  288.         return scrollUnit[vhs];
  289. }
  290.  
  291.  
  292. pascal void TScroller::AutoScroll(const VPoint& viewPt,
  293.                                   VPoint& delta)
  294. {
  295.     VRect myExtent;
  296.  
  297.     delta = gZeroVPt;
  298.     this->GetExtent(myExtent);
  299.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  300.         if (viewPt[vhs] < myExtent[topLeft][vhs])
  301.         {
  302.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  303.             VCoordinate temp = -ProportionalScroll(myExtent[topLeft][vhs] - viewPt[vhs], fScrollUnit, fTranslation[vhs], vhs);
  304.             delta[vhs] = temp;
  305.         }
  306.         else if (viewPt[vhs] > myExtent[botRight][vhs])
  307.         {
  308.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  309.             VCoordinate temp1 = ProportionalScroll(viewPt[vhs] - myExtent[botRight][vhs], fScrollUnit, fMaxTranslation[vhs] - fTranslation[vhs], vhs);
  310.             delta[vhs] = temp1;
  311.         }
  312. }
  313.  
  314. //--------------------------------------------------------------------------------------------------
  315. #pragma segment MAOpen
  316.  
  317. pascal void TScroller::CreateTemplateScrollBar(VHSelect itsDirection)
  318. {
  319.     TScrollerScrollBar * aScrollerScrollBar;
  320.     FailInfo fi;
  321.  
  322.     if (fi.Try())
  323.     {
  324.         aScrollerScrollBar = (TScrollerScrollBar *)(gViewServer->DoCreateViews(fDocument, fSuperView, kScrollBarId, gZeroVPt));
  325.         aScrollerScrollBar->fDirection = itsDirection;/* !!!Unfortunately this is not part of the
  326.                                                   resource */
  327.         aScrollerScrollBar->fShown = fShown;    // Only wants to show if we want to show 
  328.         aScrollerScrollBar->AttachScroller(this);
  329.         fi.Success();
  330.     }
  331.     else    // Recover
  332.     {
  333.         this->Free();
  334.         fi.ReSignal();
  335.     }
  336. }
  337.  
  338. //--------------------------------------------------------------------------------------------------
  339. #pragma segment MAOpen
  340.  
  341. pascal void TScroller::CreateScrollBar(VHSelect itsDirection)
  342. {
  343.     TScrollerScrollBar * aScrollerScrollBar;
  344.     FailInfo fi;
  345.  
  346.     if (fi.Try())
  347.     {
  348.         aScrollerScrollBar = new TScrollerScrollBar;
  349.         aScrollerScrollBar->IScrollerScrollBar(fSuperView, gZeroVPt, gZeroVPt, sizeVariable, sizeVariable, itsDirection, fMaxTranslation[itsDirection], this);
  350.         fi.Success();
  351.     }
  352.     else    // Recover
  353.     {
  354.         this->Free();
  355.         fi.ReSignal();
  356.     }
  357. }
  358.  
  359. //--------------------------------------------------------------------------------------------------
  360. #pragma segment MAScroll
  361.  
  362. pascal void DoPageScroll(short partCode, TScroller* aScroller)
  363. {
  364.     if (aScroller && aScroller->fScrollBars[vSel])
  365.     {
  366.         aScroller->fScrollBars[vSel]->DeltaValue(VCoordinate(aScroller->ScrollStep(vSel, partCode)));
  367.     }
  368.     aScroller->Update();
  369. }
  370.  
  371. #pragma segment MAScroll
  372. pascal void TScroller::DoKeyCommand(TToolboxEvent* event)// override 
  373. {
  374.     if (this->IsEnabled() && fRespondsToFunctionKeys)
  375.         switch (event->fCharacter)
  376.         {
  377.             case chPageUp:
  378.                 DoPageScroll(inPageUp, this);
  379.                 break;
  380.                 
  381.             case chPageDown:
  382.                 DoPageScroll(inPageDown, this);
  383.                 break;
  384.                 
  385.             case chHome:
  386.                 this->ScrollTo(gZeroVPt, kRedraw);
  387.                 this->Update();
  388.                 break;
  389.                 
  390.             case chEnd:
  391.                 this->ScrollTo(fMaxTranslation, kRedraw);
  392.                 this->Update();
  393.                 break;
  394.                 
  395.             default:
  396.                 inherited::DoKeyCommand(event);
  397.                 break;
  398.         }
  399.     else
  400.         inherited::DoKeyCommand(event);
  401. }
  402.  
  403. //--------------------------------------------------------------------------------------------------
  404. #pragma segment MAScroll
  405.  
  406. pascal void TScroller::DoScroll(const VPoint& delta,
  407.                                 Boolean redraw)
  408. {
  409.     VPoint localDelta(delta);
  410.  
  411.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  412.     {
  413.         if (localDelta[vhs] < 0)
  414.         {
  415.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  416.             long temp = Max(localDelta[vhs], -fTranslation[vhs]);
  417.             localDelta[vhs] = temp;
  418.         }
  419.         else if (localDelta[vhs] > 0)
  420.         {
  421.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  422.             long temp1 = Min(localDelta[vhs], (fMaxTranslation[vhs] - fTranslation[vhs]));
  423.             localDelta[vhs] = temp1;
  424.         }
  425.         fTranslation[vhs] += localDelta[vhs];
  426.     }
  427.  
  428.     if (localDelta != gZeroVPt)
  429.     {
  430.         this->InvalidateFocus();
  431.         this->UpdateCoordinates();
  432.  
  433.         // !!! In the future the decision will be made differently as to how to render
  434.         if (redraw)
  435.             this->ScrollDraw(localDelta, kInvalidate);
  436.     }
  437. }
  438.  
  439. //--------------------------------------------------------------------------------------------------
  440. #pragma segment BBFields
  441.  
  442. pascal void TScroller::Fields(TObject* obj)        // override 
  443. {
  444.     obj->DoToField("TScroller", (Ptr)NULL, bClass);
  445.     obj->DoToField("fScrollLimit", (Ptr) & fScrollLimit, bVPoint);
  446.     obj->DoToField("fMaxTranslation", (Ptr) & fMaxTranslation, bVPoint);
  447.     obj->DoToField("fScrollBars[vSel]", (Ptr) & fScrollBars[vSel], bObject);
  448.     obj->DoToField("fScrollBars[hSel]", (Ptr) & fScrollBars[hSel], bObject);
  449.     obj->DoToField("fScrollUnit", (Ptr) & fScrollUnit, bPoint);
  450.     obj->DoToField("fSBarOffsets", (Ptr) & fSBarOffsets, bVRect);
  451.     obj->DoToField("fConstrain[hSel]", (Ptr) & fConstrain[hSel], bBoolean);
  452.     obj->DoToField("fConstrain[vSel]", (Ptr) & fConstrain[vSel], bBoolean);
  453.     obj->DoToField("fRespondsToFunctionKeys", (Ptr) & fRespondsToFunctionKeys, bBoolean);
  454.  
  455.     inherited::Fields(obj);
  456. }
  457.  
  458. //--------------------------------------------------------------------------------------------------
  459. #pragma segment MAScrollerRes
  460.  
  461. pascal void TScroller::ForceRedraw(void)        // override 
  462. {
  463.     inherited::ForceRedraw();
  464.     
  465.     if (fScrollBars[hSel])
  466.         fScrollBars[hSel]->ForceRedraw();
  467.     if (fScrollBars[vSel])
  468.         fScrollBars[vSel]->ForceRedraw();
  469. }
  470.  
  471. //--------------------------------------------------------------------------------------------------
  472. #pragma segment MAScrollerRes
  473.  
  474. pascal TScroller* TScroller::GetScroller(Boolean)
  475. {
  476.     return this;
  477. }
  478.  
  479. //--------------------------------------------------------------------------------------------------
  480. #pragma segment MAScrollerRes
  481.  
  482. pascal void TScroller::HaveScrollBar(TScrollerScrollBar* theScrollBar,
  483.                                      VHSelect direction)
  484. {
  485. #if qDebug
  486.     if ((theScrollBar) && (theScrollBar->fDirection != direction))
  487.         ProgramBreak("Scroll bar is wrong direction.");
  488. #endif
  489.  
  490.     fScrollBars[direction] = theScrollBar;
  491. }
  492.  
  493. //--------------------------------------------------------------------------------------------------
  494. #pragma segment MANonRes
  495.  
  496. pascal void TScroller::Locate(const VPoint& newLoc,
  497.                               Boolean invalidate)// override 
  498. {
  499.     inherited::Locate(newLoc, invalidate);
  500.  
  501.     this->AdjustScrollBars(invalidate);
  502. }
  503.  
  504. //--------------------------------------------------------------------------------------------------
  505. #pragma segment MANonRes
  506.  
  507. pascal void TScroller::RemoveSubView(TView* theSubView)// override 
  508. {
  509.     theSubView->BeInScroller(NULL);
  510.     inherited::RemoveSubView(theSubView);
  511. }
  512.  
  513. //--------------------------------------------------------------------------------------------------
  514. #pragma segment MANonRes
  515.  
  516. pascal void TScroller::Resize(const VPoint& newSize,
  517.                               Boolean invalidate)// override 
  518. {
  519.     Boolean sBarWasVisible[2];
  520.  
  521.     // If the scroll bars are visible, erase them now so that they aren't temporarily
  522.     // displayed in the wrong place.
  523.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  524.     {
  525.         if ((fScrollBars[vhs] != NULL) && (fScrollBars[vhs]->Focus()) && (fScrollBars[vhs]->IsCMgrVisible()))
  526.         {
  527.             sBarWasVisible[vhs] = TRUE;
  528.             if (!invalidate)
  529.                 HideControl((fScrollBars[vhs])->fCMgrControl);
  530.             else
  531.                 fScrollBars[vhs]->SetCMgrVisibility(FALSE);
  532.         }
  533.         else
  534.             sBarWasVisible[vhs] = FALSE;
  535.     }
  536.  
  537.     inherited::Resize(newSize, invalidate);
  538.     
  539.     this->AdjustScrollBars(invalidate);
  540.     this->SetScrollLimits(fScrollLimit.Copy(), kDontRedraw);        // Readjust sbar maximums and fMaxTranslation
  541.  
  542.     for (vhs = vSel; vhs <= hSel; ++vhs)
  543.         if (sBarWasVisible[vhs])
  544.             fScrollBars[vhs]->SetCMgrVisibility(TRUE);
  545. }
  546.  
  547. //--------------------------------------------------------------------------------------------------
  548. #pragma segment MAScroll
  549.  
  550. pascal void TScroller::RevealRect(const VRect& rectToReveal,
  551.                                   const VPoint& minToSee,
  552.                                   Boolean redraw)// override 
  553. {
  554.     VRect myExtent;
  555.     VCoordinate minAmt;
  556.     VCoordinate coord;
  557.     VPoint delta;
  558.  
  559.  
  560.     this->GetExtent(myExtent);
  561.  
  562.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  563.     {
  564.         minAmt = Min(myExtent.Length(vhs), minToSee[vhs]);
  565.         coord = rectToReveal[topLeft][vhs] + minAmt - myExtent[botRight][vhs];
  566.         if (coord <= 0)
  567.             coord = Min(0, rectToReveal[botRight][vhs] - minAmt - myExtent[topLeft][vhs]);
  568.         delta[vhs] = coord;
  569.     }
  570.  
  571.     this->ScrollBy(delta, redraw);
  572. }
  573.  
  574. //--------------------------------------------------------------------------------------------------
  575. #pragma segment MAScroll
  576.  
  577. pascal void TScroller::ScrollBy(const VPoint& delta,
  578.                                 Boolean redraw)
  579. {
  580.     if (delta != gZeroVPt)
  581.     {
  582.         if (fScrollBars[vSel])
  583.             fScrollBars[vSel]->DeltaValue(delta.v);
  584.             
  585.         if (fScrollBars[hSel])
  586.             fScrollBars[hSel]->DeltaValue(delta.h);
  587.  
  588.         this->DoScroll(delta, redraw);
  589.     }
  590. }
  591.  
  592. //--------------------------------------------------------------------------------------------------
  593. #pragma segment MAScroll
  594.  
  595. pascal void TScroller::ScrollDraw(const VPoint& delta,
  596.                                   Boolean invalidate)
  597. {
  598.     Rect visRect;
  599.  
  600.     if (this->Focus())
  601.     {
  602.         this->GetDrawableQDRect(visRect);
  603.  
  604.         if (gIntenseDebugging)
  605.             WriteFocus();
  606.  
  607.         if (!visRect.Empty())
  608.         {
  609.             if ((labs(delta.h) > kMaxCoord) || (labs(delta.v) > kMaxCoord))// too far to scrollrect 
  610.                 this->InvalidateRect(visRect);
  611.             else
  612.             {
  613. #if qDebug
  614.                 UseTempRgn2("TScroller.ScrollDraw");
  615. #endif
  616.                 ScrollRect(visRect, (short)(-delta.h), (short)(-delta.v), gTempRgn2);
  617.                 this->InvalidateRgn(gTempRgn2);
  618. #if qDebug
  619.                 DoneWithTempRgn2();
  620. #endif
  621.             }
  622.         
  623.             if (!invalidate)
  624.                 this->Update();
  625.                 
  626.             // ??? EndUpdate(thePort);
  627.         }
  628.     }
  629. }
  630.  
  631. //--------------------------------------------------------------------------------------------------
  632. #pragma segment MAScroll
  633.  
  634. pascal VCoordinate TScroller::ScrollRelative(VHSelect vhs,
  635.                                              VCoordinate sBarValue)
  636. {
  637.     VPoint pixelDelta = gZeroVPt;
  638.     VCoordinate newValue;
  639.  
  640.     if ((fConstrain[vhs] && (sBarValue != fMaxTranslation[vhs])))
  641.         newValue = (sBarValue + fScrollUnit[vhs] / 2) / fScrollUnit[vhs] * fScrollUnit[vhs];
  642.     else
  643.         newValue = sBarValue;
  644.  
  645.     pixelDelta[vhs] = newValue - fTranslation[vhs];
  646.     this->DoScroll(pixelDelta, kRedraw);
  647.     return (newValue - sBarValue);
  648. }
  649.  
  650. //--------------------------------------------------------------------------------------------------
  651. #pragma segment MAScroll
  652.  
  653. pascal VCoordinate TScroller::ScrollStep(VHSelect vhs,
  654.                                          short partCode)
  655. {
  656.     short scrollUnit = (short)fScrollUnit[vhs];
  657.     VCoordinate delta;
  658.     VCoordinate adjustment;
  659.     VPoint deltaPt = gZeroVPt;
  660.  
  661.     switch (partCode)
  662.     {
  663.         case inUpButton:
  664.         case inDownButton:
  665.             delta = scrollUnit;
  666.             break;
  667.             
  668.         case inPageUp:
  669.         case inPageDown:
  670.             delta = fSize[vhs];
  671.             break;
  672.             
  673. #if qDebug
  674.         default:
  675.             {
  676.             Str255 theString;
  677.             ConcatNumber("TScroller::ScrollStep: bad part code =", partCode, theString);
  678.             ProgramBreak(theString);
  679.             break;
  680.             }
  681. #endif
  682.  
  683.     }
  684.  
  685.     if ((partCode == inUpButton) || (partCode == inPageUp))
  686.         delta = -delta;
  687.  
  688.     // Constrain if necessary 
  689.     if (fConstrain[vhs] && (scrollUnit != 0))
  690.     {
  691.         adjustment = (Max(0, fTranslation[vhs] + delta)) % scrollUnit;
  692.         if (adjustment != 0)
  693.             if (delta > 0)
  694.                 delta -= adjustment;
  695.             else
  696.                 delta += (scrollUnit - adjustment);
  697.     }
  698.     deltaPt[vhs] = delta;
  699.  
  700.     this->DoScroll(deltaPt, kRedraw);
  701.     return delta;
  702. }
  703.  
  704. //--------------------------------------------------------------------------------------------------
  705. #pragma segment MAScroll
  706.  
  707. pascal void TScroller::ScrollTo(const VPoint& scrollLoc,
  708.                                 Boolean redraw)
  709. {
  710.     this->SetLocalOrigin(scrollLoc, redraw);
  711. }
  712.  
  713. //--------------------------------------------------------------------------------------------------
  714. #pragma segment MAScroll
  715.  
  716. pascal void TScroller::SetLocalOrigin(const VPoint& newOrigin,
  717.                                       Boolean redraw)
  718. {
  719.     this->ScrollBy(newOrigin - fTranslation, redraw);
  720. }
  721.  
  722. //--------------------------------------------------------------------------------------------------
  723. #pragma segment MANonRes
  724.  
  725. pascal void TScroller::SetScrollLimits(const VPoint& scrollLimit,
  726.                                        Boolean drawScrollBars)
  727. {
  728.     VPoint newTranslation(fTranslation);
  729.  
  730.     fScrollLimit = scrollLimit;
  731.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  732.     {
  733.         VCoordinate maxCoord = Max(0, scrollLimit[vhs] - fSize[vhs]);
  734.         if (maxCoord != fMaxTranslation[vhs])
  735.         {
  736.             fMaxTranslation[vhs] = maxCoord;
  737.             if (fScrollBars[vhs])
  738.                 fScrollBars[vhs]->SetLongMax(maxCoord, drawScrollBars);
  739.  
  740.             if (maxCoord < fTranslation[vhs])
  741.                 newTranslation[vhs] = maxCoord;
  742.         }
  743.     }
  744.  
  745.     if (newTranslation != fTranslation)
  746.         this->ScrollTo(newTranslation, kRedraw);
  747. }
  748.  
  749. //--------------------------------------------------------------------------------------------------
  750. #pragma segment MANonRes
  751.  
  752. pascal void TScroller::SetScrollParameters(const VPoint& units,
  753.                                            Boolean horzConstraint,
  754.                                            Boolean vertConstraint)
  755. {
  756.     fScrollUnit = units;
  757.     fConstrain[hSel] = horzConstraint;
  758.     fConstrain[vSel] = vertConstraint;
  759. }
  760.  
  761. //--------------------------------------------------------------------------------------------------
  762. #pragma segment MANonRes
  763.  
  764. pascal void TScroller::SubViewChangedSize(TView* ,
  765.                                           const VPoint&)// override 
  766. {
  767.     VPoint aVPoint = gZeroVPt;
  768.     CSubViewIterator iter(this);
  769.     
  770.     for(TView* theSubView = iter.FirstSubView(); iter.More(); theSubView = iter.NextSubView())
  771.     {
  772.         aVPoint.v = Max(aVPoint.v, theSubView->fLocation.v + theSubView->fSize.v);
  773.         aVPoint.h = Max(aVPoint.h, theSubView->fLocation.h + theSubView->fSize.h);
  774.     }
  775.  
  776.     this->SetScrollLimits(aVPoint, kRedraw);
  777. }
  778.  
  779.  
  780.